﻿using System.Text;

namespace Bootstrap5.Design;

internal class CssUtilityDecoratorProvider : ClassDecoratorProvider,ICssUtilityDecorator
{
    public CssUtilityDecoratorProvider()
    {

    }
    internal ICssUtilityDecorator SetClass(StringBuilder builder)
        =>SetClass(builder.ToString());
    internal ICssUtilityDecorator SetClass(string value)
    {
        if (!Rules.Contains(value))
        {
            Rules.Add(value);
        }
        return this;
    }

    protected override void BuildClass()
    {
    }

    public ICssUtilityDecorator Visibility(Visibility visibility) => SetClass(visibility.GetEnumCssClass());


    #region Position

    public ICssUtilityDecorator Position(Position position) => SetClass($"position{position.GetEnumCssClass("-")}");

    public ICssUtilityDecorator AtPosition(PositionKey position, PositionValue value)
        => SetClass( $"{position.GetEnumCssClass()}{value.GetEnumCssClass("-")}");

    public ICssUtilityDecorator TranslateMiddle(Side? coordinate = null)
    => SetClass($"translate-middle{coordinate?.GetEnumCssClass("-")}");
    #endregion

    public ICssUtilityDecorator FontMonoSpace => SetClass("font-monospace");

    public ICssUtilityDecorator Width(LengthPercent percent, LengthLimitation? limitation = default)
    {
        var builder=new StringBuilder();
        if (limitation.HasValue)
        {
            builder.Append(limitation.GetEnumCssClass());
        }
        builder.AppendFormat("w-{0}",percent.GetEnumCssClass());
        return SetClass(builder.ToString());
    }

    public ICssUtilityDecorator Height(LengthPercent percent, LengthLimitation? limitation = default)
    {
        var builder = new StringBuilder();
        if (limitation.HasValue)
        {
            builder.Append(limitation.GetEnumCssClass());
        }
        builder.AppendFormat("h-{0}", percent.GetEnumCssClass());
        return SetClass(builder.ToString());
    }

    public ICssUtilityDecorator VerticalAlign(VerticalAlign alignment)
    => SetClass($"align-{alignment.GetEnumCssClass()}");

    public ICssUtilityDecorator Text(Text text, BreakPoint? breakPoint = default)
    => SetClass($"text{breakPoint?.GetEnumCssClass()}-{text.GetEnumCssClass()}");

    public ICssUtilityDecorator TextDecoration(TextDecoration decoration)
    => SetClass($"text-decoration-{decoration.GetEnumCssClass()}");

    public ICssUtilityDecorator FontWeight(FontWeight fontWeight)
    => SetClass($"fw-{fontWeight.GetEnumCssClass()}");

    public ICssUtilityDecorator FontSize(FontSize fontSize)
    => SetClass($"fs-{fontSize.GetEnumCssClass()}");

    public ICssUtilityDecorator FontStyle(FontStyle fontStyle)
    => SetClass($"fst-{fontStyle.GetEnumCssClass()}");

    public ICssUtilityDecorator LineHeight(LineHeight lineHeight)
    => SetClass($"lh-{lineHeight.GetEnumCssClass()}");

    public ICssUtilityDecorator Shadow(Shadow? shadow = null)
    => SetClass($"shadow{shadow?.GetEnumCssClass("-")}");

    public ICssUtilityDecorator Margin(SpaceNum num, SpaceSide? side = default, BreakPoint? breakPoint = default)
    => Space(Spacing.Margin, num, side, breakPoint);

    public ICssUtilityDecorator Padding(SpaceNum num, SpaceSide? side = default, BreakPoint? breakPoint = default)
    => Space(Spacing.Padding, num, side, breakPoint);

    ICssUtilityDecorator Space(Spacing space, SpaceNum num, SpaceSide? side = default, BreakPoint? breakPoint = default)
    {
        var builder=new StringBuilder(space.GetEnumCssClass());
        if (side.HasValue)
        {
            builder.Append(side.GetEnumCssClass());
        }
        builder.Append(breakPoint?.GetEnumCssClass("-"));
        builder.Append('-');
        builder.Append(num.GetEnumCssClass());
        SetClass(builder.ToString());
        return this;
    }

    public ICssUtilityDecorator Gutter(Num num, Side? side, BreakPoint? breakPoint = null)
    {
        var builder = new StringBuilder("g");
        if (side.HasValue)
        {
            builder.Append(side.GetEnumCssClass());
        }
        builder.Append(breakPoint?.GetEnumCssClass("-"));
        builder.Append('-');
        builder.Append(num.GetEnumCssClass());
        SetClass(builder.ToString());
        return this;
    }

    public ICssUtilityDecorator Overflow(Overflow overflow) => SetClass($"overflow-{overflow.GetEnumCssClass()}");

    public ICssUtilityDecorator UserSelect(UserSelect select) => SetClass($"user-select-{select.GetEnumCssClass()}");

    public ICssUtilityDecorator PointEvent(PointEvent e) => SetClass($"pe-{e.GetEnumCssClass()}");
    public ICssUtilityDecorator Float(Float @float, BreakPoint? breakPoint = default)=> SetClass($"float{breakPoint?.GetEnumCssClass("-")}-{@float.GetEnumCssClass()}");

    public ICssUtilityDecorator FlexOrientation(FlexOrientation orientation, BreakPoint? breakPoint = null, bool reserve = false)
    {
        var builder = new StringBuilder("flex");
        builder.Append(breakPoint?.GetEnumCssClass("-"));
        builder.Append(orientation.GetEnumCssClass("-"));
        if (reserve)
        {
            builder.Append("-reserve");
        }
        SetClass(builder.ToString());
        return this;
    }

    public ICssUtilityDecorator JustifyContent(JustifyContent content, BreakPoint? breakPoint = null)
    => SetClass($"justify-content{breakPoint?.GetEnumCssClass("-")}-{content.GetEnumCssClass()}");

    public ICssUtilityDecorator AlignItems(AlignItemsOrSelf alignItems, BreakPoint? breakPoint = null)
    => SetClass($"align-items{breakPoint?.GetEnumCssClass("-")}-{alignItems.GetEnumCssClass()}");

    public ICssUtilityDecorator AlignSelf(AlignItemsOrSelf alignSelf, BreakPoint? breakPoint = null)
    => SetClass($"align-self{breakPoint?.GetEnumCssClass("-")}-{alignSelf.GetEnumCssClass()}");

    public ICssUtilityDecorator AlignContent(AlignContent content, BreakPoint? breakPoint = null)
    => SetClass($"align-content{breakPoint?.GetEnumCssClass("-")}-{content.GetEnumCssClass()}");
    public ICssUtilityDecorator FlexFill(BreakPoint? breakPoint = null)
    => SetClass($"flex{breakPoint?.GetEnumCssClass("-")}-fill");

    public ICssUtilityDecorator FlexGrow(bool grow = true, BreakPoint? breakPoint = null)
    => SetClass($"flex{breakPoint?.GetEnumCssClass("-")}-grow{(grow ? "-1" : "-0")}");

    public ICssUtilityDecorator FlexShrink(bool shrink = true, BreakPoint? breakPoint = null)
    => SetClass($"flex{breakPoint?.GetEnumCssClass("-")}-shrink{(shrink ? "-1" : "-0")}");

    public ICssUtilityDecorator FlexWrap(bool wrap = true, BreakPoint? breakPoint = null, bool reserve = false)
    => SetClass($"flex{breakPoint?.GetEnumCssClass("-")}-{(wrap ? "wrap" : "nowrap")}{(reserve ? "-reverse" : null)}");

    public ICssUtilityDecorator FlexOrder(FlexOrder order, BreakPoint? breakPoint = null)
    => SetClass($"order{breakPoint?.GetEnumCssClass("-")}-{order.GetEnumCssClass()}");

    public ICssUtilityDecorator Display(DisplayType display, BreakPoint? breakPoint = default, bool print = default)
        => SetClass($"d{(print ? "print" : breakPoint?.GetEnumCssClass("-"))}-{display.GetEnumCssClass()}");

    public ICssUtilityDecorator BgColor(BgColor color, bool gradient = false)
    {
        var builder = new StringBuilder($"bg-{color.GetEnumCssClass()}");
        if (gradient)
        {
            builder.Append(" bg-gradient");
        }
        return SetClass(builder);
    }

    public ICssUtilityDecorator Border(Placement? orientation = null, bool subtractive = false)
    {
        var builder =new StringBuilder("border");
        if (orientation.HasValue)
        {
            builder.Append($" border-{orientation.GetEnumCssClass()}");
        }
        if (subtractive)
        {
            builder.Append("-0");
        }
        return SetClass(builder);
    }

    public ICssUtilityDecorator BorderColor(Color color) => SetClass($"border-{color.GetEnumCssClass()}");

    public ICssUtilityDecorator BorderWidth(Num num) => SetClass($"border-{num.GetEnumCssClass()}");

    public ICssUtilityDecorator TextColor(TextColor color) => SetClass($"text-{color.GetEnumCssClass()}");
    public ICssUtilityDecorator BorderRadius(BorderRadius? radius = default) => SetClass($"rounded{radius?.GetEnumCssClass("-")}");

    public ICssUtilityDecorator StretchedLink =>SetClass("stretched-link");
    public ICssUtilityDecorator VisuallyHidden(bool focusable = default) => SetClass($"visually-hidden{(focusable ? "-focusable" : null)}");
    public ICssUtilityDecorator LinkColor(Color color) => SetClass($"link-{color.GetEnumCssClass()}");
    public ICssUtilityDecorator ClearFix => SetClass("clearfix");
    public ICssUtilityDecorator Gap(Num gap) => SetClass($"gap-{gap.GetEnumCssClass()}");
    public ICssUtilityDecorator CssClass(string value) => SetClass(value);
    public ICssUtilityDecorator NavBar(NavBarClass navBar) => SetClass($"navbar-{navBar.GetEnumCssClass()}");

    public ICssUtilityDecorator Head(HeadSize size) => SetClass($"{size.GetEnumCssClass()}");

    public ICssUtilityDecorator Display(DisplaySize size) => SetClass($"display-{size.GetEnumCssClass()}");

    public ICssUtilityDecorator Lead() => SetClass("lead");

    public ICssUtilityDecorator Small() => SetClass("small");

    public ICssUtilityDecorator Mark() => SetClass("mark");

    public ICssUtilityDecorator Initialism() => SetClass("initialism");

    public ICssUtilityDecorator Blockquote() => SetClass("blockquote");

    public ICssUtilityDecorator BlockquoteFooter() => SetClass("blockquote-footer");

    public ICssUtilityDecorator ListUnstyled() => SetClass("list-unstyled");

    public ICssUtilityDecorator CardText() => SetClass("card-text");

    public ICssUtilityDecorator CardTitle() => SetClass("card-title");

    public ICssUtilityDecorator CardSubTitle() => SetClass("card-subtitle");

    public ICssUtilityDecorator CardLink() => SetClass("card-link");

    public ICssUtilityDecorator CardImageOverlay() => SetClass("card-img-overlay");

    public ICssUtilityDecorator Show() => SetClass("show");

    public ICssUtilityDecorator Hide() => SetClass("hide");
}
